package com.lry.sso.auth.server.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lry.sso.auth.common.bean.RequestInfoContext;
import com.lry.sso.auth.common.util.HttpUtils;
import com.lry.sso.common.entity.response.ResultData;
import com.lry.sso.common.entity.response.Ret;
import com.lry.sso.common.exception.SysErrorEnum;
import com.lry.sso.common.exception.SysInvocationException;
import com.lry.sso.common.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 请求与响应处理
 *
 * @author 李瑞益
 * @date 2019/12/8
 */
//@Component
//@WebFilter(urlPatterns = "/*")
//@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public class RequestFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(RequestFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hres = (HttpServletRequest) request;
        logger.info("请求路径：{}", hres.getRequestURI());
        Map<String, String[]> parameterMap = hres.getParameterMap();
        String body = JSON.toJSONString(parameterMap);
        logger.info("路径参数：{}", body);
        logger.info("进入请求包装类");
        RequestWrapper rw = new RequestWrapper((HttpServletRequest) request);
        String json = rw.getBody();
        if (!StringUtils.isEmpty(json)) {
            logger.info("请求体参数：{}",json);
            JSONObject jsonObject = JSON.parseObject(json);
            //对string类型的参数进行trim操作；
            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                this.paramHandler(entry);
            }
            logger.info("处理完后的请求体：{}", jsonObject.toJSONString());
            rw.setBody(jsonObject.toJSONString());
        }
        logger.info("结束请求包装类");

        ResponseWrapper wrapper = new ResponseWrapper((HttpServletResponse) response);
        String content = "";
        try {
            chain.doFilter(rw, wrapper);
            content = new String(wrapper.toByteArray(), StandardCharsets.UTF_8);
        } catch (Exception e) {
            ResultData error = null;
            if (e instanceof SysInvocationException) {
                error = Ret.error(((SysInvocationException) e).getError());
            } else {
                error = Ret.error(SysErrorEnum.SYSTEM.code(), e.getMessage());
            }
            logger.error("异常信息：{}", JSON.toJSONString(error));
            content = JSON.toJSONString(error);
            e.printStackTrace();
        }
        logger.info("响应消息：{}", content);
        RequestInfoContext.remove();
        HttpUtils.writeResponse((HttpServletResponse) response, wrapper.getStatus(), content);

    }

    /**
     * 处理请求参数
     * @param sourceEntry JSON化参数的entry
     */
    private void paramHandler(Map.Entry<String, Object> sourceEntry) {
        Object obj = sourceEntry.getValue();
        if (obj instanceof Map) {
            for (Map.Entry<String, Object> entry : ((Map<String, Object>) obj).entrySet()) {
                this.paramHandler(entry);
            }
        } else if (isNoNullStringClass(obj)) {
            sourceEntry.setValue(((String) obj).trim());
//        } else if (obj instanceof JSONArray[]) {
//            sourceEntry.setValue(jsonArrays((JSONArray[])obj));
        } else if (obj instanceof JSONArray) {
            sourceEntry.setValue(jsonArrayHandler((JSONArray)obj));
        }
    }

    /**
     * JSONArray[]
     *
     * @param values
     */
//    private JSONArray[] jsonArrays(JSONArray[] values) {
//        JSONArray[] newValue = new JSONArray[values.length];
//        for (int i = 0; i < values.length; i++) {
//            for (int j = 0; j < values[i].size(); j++) {
//                newValue[i].set(j,jsonArray(values[i].get(j)));
//                newValue[i] = jsonArray(values[i].get(j));
//            }
//        }
//        return newValue;
//    }

    /**
     * JSONArray
     * @param ja 参数JSONArray
     * @return 处理过的JSONArray
     */
    private JSONArray jsonArrayHandler(JSONArray ja) {
        JSONArray newJa = new JSONArray();
        for (int i = 0; i < ja.size(); i++) {
            if (isNoNullStringClass(ja.get(i))) {
                newJa.add(StringHelper.valueOf(ja.get(i)).trim());
            }else
            if (ja.get(i) instanceof Map) {
                paramHandler((Map.Entry<String, Object>) ja.get(i));
//            } else if (ja.get(i) instanceof JSONArray[]) {
//                jsonArrays((JSONArray[])ja.get(i));
            } else if (ja.get(i) instanceof JSONArray) {
                newJa.add(jsonArrayHandler((JSONArray)ja.get(i)));
            }
        }
        return newJa;
    }

    /**
     * 判断是否是string类型且 不为空
     * @param object 对象
     * @return true：是string类型，不为空
     */
    private boolean isNoNullStringClass(Object object) {
        return object instanceof String && !StringUtils.isEmpty(object);
    }
}
